﻿/**
 * Peter
 * Created by: Peter Development Team
 *    http://peter.codeplex.com/
 * 
 * GNU General Public License version 2 (GPLv2)
 *    http://peter.codeplex.com/license
 *
 *  This code is provided on an AS IS basis, with no WARRANTIES,
 *  CONDITIONS or GUARANTEES of any kind.
 *
 **/

using System;
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.Windows.Input;
using System.Xml.Serialization;
using Peter.Common;
using Peter.Common.Interfaces;
using Peter.Common.MainMenu;
using Peter.Common.Utilities;
using Peter.Ftp.Data;
using Peter.Ftp.View;

namespace Peter.Ftp.Logic
{
   /// <summary>
   /// Represents the option page for the ftp plugin.
   /// </summary>
   [Export (typeof (IOptionPage))]
   public class OptionsFtp : ViewModelBase, IOptionPage, IPartImportsSatisfiedNotification
   {
      private bool m_UploadOnSave;
      private RelayCommand m_AddConnection;
      private RelayCommand m_RemoveConnection;
      private FtpConnectionData m_SelectedConnection;

      /// <summary>
      /// The name of the options page.
      /// </summary>
      public const string PAGE_NAME = "Peter FTP";

      /// <summary>
      /// Initializes a new ftp options object.
      /// </summary>
      public OptionsFtp ()
      {
         if (!ViewRegistry.Contains (typeof (OptionsFtp)))
            ViewRegistry.Register (typeof (OptionsFtp), typeof (ViewFtpOptions));
         this.FtpConnections = new ObservableCollection<FtpConnectionData> ();
      }

      /// <summary>
      /// Gets the name of the option page.
      /// </summary>
      [XmlIgnore]
      public string Name
      {
         get { return PAGE_NAME; }
      }

      /// <summary>
      /// Gets the icon of the option page.
      /// </summary>
      [XmlIgnore]
      public MainMenuIcon OptionPageIcon
      {
         get { return MainMenuIcon.Ftp; }
      }

      /// <summary>
      /// Gets the peter data.
      /// </summary>
      [XmlIgnore]
      [Import (typeof (IPeterData))]
      public IPeterData PeterData { get; set; }

      /// <summary>
      /// Gets the list of sessions.
      /// </summary>
      public ObservableCollection<FtpConnectionData> FtpConnections { get; set; }

      /// <summary>
      /// Gets or Sets if a file opened through ftp should be uploaded to the server when saved.
      /// </summary>
      public bool UploadOnSave
      {
         get { return this.m_UploadOnSave; }
         set
         {
            this.m_UploadOnSave = value;
            this.OnPropertyChanged ("UploadOnSave");
         }
      }

      /// <summary>
      /// Gets or Sets the selected connection.
      /// </summary>
      [XmlIgnore]
      public FtpConnectionData SelectedConnection
      {
         get { return this.m_SelectedConnection; }
         set
         {
            this.m_SelectedConnection = value;
            this.OnPropertyChanged ("SelectedConnection");
         }
      }

      /// <summary>
      /// Gets the Add connection command.
      /// </summary>
      public ICommand AddConnection
      {
         get { return m_AddConnection ?? (this.m_AddConnection = new RelayCommand (this.OnAddConnection)); }
      }

      /// <summary>
      /// Gets the Remove connection command.
      /// </summary>
      public ICommand RemoveConnection
      {
         get
         {
            return m_RemoveConnection ??
                   (this.m_RemoveConnection = new RelayCommand (this.OnRemoveConnection,
                                                                delegate
                                                                   {
                                                                      return this.SelectedConnection != null;
                                                                   }));
         }
      }

      /// <summary>
      /// Occurs when the add connection is invoked.
      /// </summary>
      /// <param name="obj">Command Parameter (not used).</param>
      private void OnAddConnection (object obj)
      {
         var ftpData = new FtpConnectionData { Name = "New Ftp Connection" };
         this.FtpConnections.Add (ftpData);
         this.SelectedConnection = ftpData;
      }

      /// <summary>
      /// Occurs when the remove connection is invoked.
      /// </summary>
      /// <param name="obj">Command Parameter (not used).</param>
      private void OnRemoveConnection (object obj)
      {
         this.FtpConnections.Remove (this.SelectedConnection);
      }

      /// <summary>
      /// Loads the data from xml.
      /// </summary>
      /// <param name="xmlToLoad">Xml string to load.</param>
      public void LoadFromXml (string xmlToLoad)
      {
         OptionsFtp loadedData = null;
         try
         {
            loadedData = Serialization.DeserializeFromString<OptionsFtp> (xmlToLoad);
         }
         catch (Exception ex)
         {
            Console.Error.Write (ex.Message);
         }

         if (loadedData != null)
            this.CopyPropertiesFrom (loadedData);
      }

      /// <summary>
      /// Saves any data to xml.
      /// </summary>
      /// <returns>The data to save in Xml format.</returns>
      public string SaveToXml ()
      {
         return this.Serialize ();
      }

      /// <summary>Called when a part's imports have been satisfied and it is safe to use.</summary>
      public void OnImportsSatisfied ()
      {
         var type = this.GetType ().ToString ();
         this.LoadFromXml (this.PeterData.RequestData (type));
      }
   }
}
